#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
过滤配置管理器模块

本模块提供了一个灵活的过滤条件管理系统，用于动态构建SQL查询中的WHERE条件。
主要功能包括：
- 定义不同类型的过滤规则
- 动态构建SQL过滤条件
- 支持多种数据类型和操作符
- 可扩展的配置化管理

使用示例：
    # 创建过滤管理器
    filter_manager = FilterConfigManager()
    
    # 获取organ_ids的过滤规则
    rules = filter_manager.get_filter_rules(['organ_ids'])
    
    # 构建SQL条件
    condition = filter_manager.build_condition_sql(rules[0], ['org123', 'org456'])
    # 结果: "organ_id IN ('org123','org456')"
    
    # 添加新的过滤规则
    new_rule = FilterRule(
        name="status",
        table="device_table",
        field="status",
        field_type=FilterType.STRING,
        description="设备状态过滤",
        condition_template="{field} = {value}"
    )
    filter_manager.add_filter_rule("status", new_rule)

Date: 2025-01-20
"""

from enum import Enum
from dataclasses import dataclass
from typing import List, Dict, Any, Optional

class FilterType(Enum):
    """
    过滤条件类型枚举
    
    定义了支持的过滤条件数据类型，用于确定如何格式化值和选择操作符。
    
    Attributes:
        STRING: 字符串类型，生成如 "field = 'value'" 的条件
        INTEGER: 整数类型，生成如 "field = 123" 的条件
        LIST: 列表类型，生成如 "field IN ('val1','val2')" 的条件
        BOOLEAN: 布尔类型，生成如 "field = true" 的条件
    
    Examples:
        >>> FilterType.STRING.value
        'string'
        >>> FilterType.LIST.value
        'list'
    """
    STRING = "string"
    INTEGER = "integer"
    LIST = "list"
    BOOLEAN = "boolean"

@dataclass
class FilterRule:
    """
    过滤规则数据类
    
    定义单个过滤规则的所有属性，包括表名、字段名、数据类型和条件模板等。
    
    Attributes:
        name (str): 过滤规则的名称，用于分组管理
        table (str): 数据库表名
        field (str): 数据库字段名
        field_type (FilterType): 字段数据类型
        description (str): 规则描述信息
        condition_template (str): SQL条件模板，支持 {field}、{operator}、{value} 占位符
    
    Examples:
        >>> # 创建一个organ_id的过滤规则
        >>> rule = FilterRule(
        ...     name="organ_ids",
        ...     table="l_lamppost",
        ...     field="organ_id",
        ...     field_type=FilterType.LIST,
        ...     description="灯杆机构过滤条件",
        ...     condition_template="{field} IN ({value})"
        ... )
        >>> 
        >>> # 创建一个状态过滤规则
        >>> status_rule = FilterRule(
        ...     name="status",
        ...     table="device",
        ...     field="status",
        ...     field_type=FilterType.STRING,
        ...     description="设备状态过滤"
        ... )
    """
    name: str
    table: str
    field: str
    field_type: FilterType
    description: str
    condition_template: str = "{field} {operator} {value}"

class FilterConfigManager:
    """
    过滤配置管理器
    
    负责管理所有的过滤规则，提供规则的增删查改功能，以及动态构建SQL条件的能力。
    这是整个过滤系统的核心类，通过配置化的方式管理各种过滤条件。
    
    主要功能：
    - 管理预定义的过滤规则（organ_ids、user_level等）
    - 支持动态添加新的过滤规则
    - 根据规则和值构建SQL WHERE条件
    - 支持不同数据类型的自动格式化
    - 提供高级条件构建功能
    
    Attributes:
        rules (Dict[str, List[FilterRule]]): 存储所有过滤规则的字典，按名称分组
    
    Examples:
        >>> # 基本使用
        >>> manager = FilterConfigManager()
        >>> 
        >>> # 获取organ_ids的所有规则
        >>> organ_rules = manager.get_filter_rules(['organ_ids'])
        >>> print(f"找到 {len(organ_rules)} 个organ_id规则")
        >>> 
        >>> # 构建SQL条件
        >>> condition = manager.build_condition_sql(organ_rules[0], ['org123', 'org456'])
        >>> print(condition)  # 输出: organ_id IN ('org123','org456')
        >>> 
        >>> # 添加自定义规则
        >>> custom_rule = FilterRule(
        ...     name="region",
        ...     table="area_table",
        ...     field="region_code",
        ...     field_type=FilterType.STRING,
        ...     description="区域过滤"
        ... )
        >>> manager.add_filter_rule("region", custom_rule)
        >>> 
        >>> # 使用高级条件构建
        >>> advanced_condition = manager.build_condition_sql_advanced(
        ...     organ_rules[0], ['org123'], "NOT IN"
        ... )
        >>> print(advanced_condition)  # 输出: organ_id NOT IN ('org123')
    """
    
    def __init__(self):
        """
        初始化过滤配置管理器
        
        自动加载预定义的过滤规则，包括organ_ids和user_level等常用规则。
        """
        self.rules = self._init_default_rules()
    
    def _init_default_rules(self) -> Dict[str, List[FilterRule]]:
        """
        初始化默认过滤规则
        
        创建系统预定义的过滤规则，包括所有需要organ_id过滤的表和user_level过滤规则。
        这些规则覆盖了系统中的主要业务表。
        
        Returns:
            Dict[str, List[FilterRule]]: 按过滤名称分组的规则字典
                - "organ_ids": 包含所有需要机构过滤的表规则
                - "user_level": 用户级别过滤规则
        
        Note:
            这个方法在类初始化时自动调用，用户通常不需要直接调用。
        """
        return {
            "organ_ids": [
                FilterRule(
                    name="organ_ids",
                    table="l_lamppost",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="b_sunrise_set",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="l_lamppost_survey_check",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="r_rtu",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="r_onoff_real_time",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="b_canton",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="l_onoff_plan",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="r_his_coplog_phase",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="r_coplog_phase",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="b_work_model",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="b_organ",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="l_coplog",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="r_control_cabinet",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="l_his_hitch_alarm",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="b_lamppost_type",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                ),
                FilterRule(
                    name="organ_ids",
                    table="p_hitch_alarm",
                    field="organ_id",
                    field_type=FilterType.LIST,
                    description="数据筛选条件",
                    condition_template="{field} IN ({value})"
                )
            ]
        }
    
    def get_filter_rules(self, filter_names: List[str]) -> List[FilterRule]:
        """
        获取指定过滤条件的规则
        
        根据过滤名称列表，返回对应的所有过滤规则。如果某个名称不存在，会被忽略。
        
        Args:
            filter_names (List[str]): 过滤条件名称列表，如 ['organ_ids', 'user_level']
        
        Returns:
            List[FilterRule]: 匹配的过滤规则列表
        
        Examples:
            >>> manager = FilterConfigManager()
            >>> rules = manager.get_filter_rules(['organ_ids'])
            >>> print(f"找到 {len(rules)} 个规则")
            >>> 
            >>> # 获取多种类型的规则
            >>> mixed_rules = manager.get_filter_rules(['organ_ids', 'user_level'])
        """
        rules = []
        for name in filter_names:
            if name in self.rules:
                rules.extend(self.rules[name])
        return rules
    
    def add_filter_rule(self, filter_name: str, rule: FilterRule):
        """
        添加新的过滤规则
        
        向指定的过滤名称组中添加新的规则。如果该名称组不存在，会自动创建。
        
        Args:
            filter_name (str): 过滤条件名称，如 'region_id', 'status' 等
            rule (FilterRule): 要添加的过滤规则对象
        
        Examples:
            >>> manager = FilterConfigManager()
            >>> 
            >>> # 添加区域过滤规则
            >>> region_rule = FilterRule(
            ...     name="region_id",
            ...     table="area_table",
            ...     field="region_code",
            ...     field_type=FilterType.STRING,
            ...     description="区域过滤条件"
            ... )
            >>> manager.add_filter_rule("region_id", region_rule)
            >>> 
            >>> # 添加状态过滤规则
            >>> status_rule = FilterRule(
            ...     name="status",
            ...     table="device_table",
            ...     field="device_status",
            ...     field_type=FilterType.STRING,
            ...     description="设备状态过滤",
            ...     condition_template="{field} = {value}"
            ... )
            >>> manager.add_filter_rule("status", status_rule)
        """
        if filter_name not in self.rules:
            self.rules[filter_name] = []
        self.rules[filter_name].append(rule)
    
    def build_condition_sql(self, rule: FilterRule, value: Any) -> str:
        """
        使用模板构建SQL条件
        
        根据过滤规则和提供的值，自动构建SQL WHERE条件。会根据字段类型自动选择
        合适的操作符和格式化方式。
        
        Args:
            rule (FilterRule): 过滤规则对象，包含表名、字段名、类型等信息
            value (Any): 过滤值，可以是字符串、数字、列表等
        
        Returns:
            str: 构建好的SQL条件字符串
        
        Examples:
            >>> manager = FilterConfigManager()
            >>> rules = manager.get_filter_rules(['organ_ids'])
            >>> 
            >>> # 单个值
            >>> condition1 = manager.build_condition_sql(rules[0], 'org123')
            >>> print(condition1)  # 输出: organ_id IN ('org123')
            >>> 
            >>> # 多个值
            >>> condition2 = manager.build_condition_sql(rules[0], ['org123', 'org456'])
            >>> print(condition2)  # 输出: organ_id IN ('org123','org456')
            >>> 
            >>> # 数字类型
            >>> user_rules = manager.get_filter_rules(['user_level'])
            >>> condition3 = manager.build_condition_sql(user_rules[0], 2)
            >>> print(condition3)  # 输出: user_level >= 2
        
        Raises:
            KeyError: 当模板中的占位符无法替换时
        """
        # 根据字段类型格式化值
        formatted_value = self._format_value(rule.field_type, value)
        
        # 根据字段类型确定操作符
        operator = self._get_operator(rule.field_type, value)
        
        # 使用模板构建条件
        condition = rule.condition_template.format(
            field=rule.field,
            operator=operator,
            value=formatted_value
        )
        
        return condition
    
    def _format_value(self, field_type: FilterType, value: Any) -> str:
        """
        根据字段类型格式化值
        
        将Python值转换为SQL中可用的格式。不同类型的值有不同的格式化规则。
        
        Args:
            field_type (FilterType): 字段数据类型
            value (Any): 要格式化的值
        
        Returns:
            str: 格式化后的SQL值字符串
        
        Examples:
            >>> manager = FilterConfigManager()
            >>> 
            >>> # 列表类型
            >>> formatted = manager._format_value(FilterType.LIST, ['a', 'b'])
            >>> print(formatted)  # 输出: 'a','b'
            >>> 
            >>> # 字符串类型
            >>> formatted = manager._format_value(FilterType.STRING, 'test')
            >>> print(formatted)  # 输出: 'test'
            >>> 
            >>> # 整数类型
            >>> formatted = manager._format_value(FilterType.INTEGER, 123)
            >>> print(formatted)  # 输出: 123
        """
        if field_type == FilterType.LIST:
            if isinstance(value, list):
                formatted_values = [f"'{v}'" for v in value]
                return ','.join(formatted_values)
            else:
                return f"'{value}'"
        elif field_type == FilterType.STRING:
            return f"'{value}'"
        elif field_type == FilterType.INTEGER:
            return str(value)
        elif field_type == FilterType.BOOLEAN:
            return str(value).lower()
        else:
            return f"'{value}'"
    
    def _get_operator(self, field_type: FilterType, value: Any) -> str:
        """
        根据字段类型和值确定操作符
        
        自动选择最适合的SQL操作符。列表类型使用IN，其他类型使用等号。
        
        Args:
            field_type (FilterType): 字段数据类型
            value (Any): 过滤值（当前版本未使用，保留用于扩展）
        
        Returns:
            str: SQL操作符字符串
        
        Examples:
            >>> manager = FilterConfigManager()
            >>> 
            >>> # 列表类型使用IN
            >>> op1 = manager._get_operator(FilterType.LIST, ['a', 'b'])
            >>> print(op1)  # 输出: IN
            >>> 
            >>> # 其他类型使用等号
            >>> op2 = manager._get_operator(FilterType.STRING, 'test')
            >>> print(op2)  # 输出: =
        """
        if field_type == FilterType.LIST:
            return "IN"
        else:
            return "="
    
    def build_condition_sql_advanced(self, rule: FilterRule, value: Any, operator: str = None) -> str:
        """
        高级条件构建，支持自定义操作符
        
        提供更灵活的条件构建功能，允许用户指定自定义的SQL操作符。
        如果不指定操作符，会根据字段类型自动选择。
        
        Args:
            rule (FilterRule): 过滤规则对象
            value (Any): 过滤值
            operator (str, optional): 自定义SQL操作符，如 'NOT IN', '>', '<', 'LIKE' 等
        
        Returns:
            str: 构建好的SQL条件字符串
        
        Examples:
            >>> manager = FilterConfigManager()
            >>> rules = manager.get_filter_rules(['organ_ids'])
            >>> 
            >>> # 使用NOT IN操作符
            >>> condition1 = manager.build_condition_sql_advanced(
            ...     rules[0], ['org123', 'org456'], 'NOT IN'
            ... )
            >>> print(condition1)  # 输出: organ_id NOT IN ('org123','org456')
            >>> 
            >>> # 使用LIKE操作符（需要相应的模板支持）
            >>> string_rule = FilterRule(
            ...     name="name_search",
            ...     table="users",
            ...     field="username",
            ...     field_type=FilterType.STRING,
            ...     description="用户名搜索",
            ...     condition_template="{field} {operator} {value}"
            ... )
            >>> condition2 = manager.build_condition_sql_advanced(
            ...     string_rule, '%admin%', 'LIKE'
            ... )
            >>> print(condition2)  # 输出: username LIKE '%admin%'
            >>> 
            >>> # 数值比较
            >>> user_rules = manager.get_filter_rules(['user_level'])
            >>> condition3 = manager.build_condition_sql_advanced(
            ...     user_rules[0], 5, '>'
            ... )
            >>> print(condition3)  # 输出: user_level > 5
        """
        formatted_value = self._format_value(rule.field_type, value)
        
        if operator is None:
            operator = self._get_operator(rule.field_type, value)
        
        # 使用模板构建条件
        condition = rule.condition_template.format(
            field=rule.field,
            operator=operator,
            value=formatted_value
        )
        
        return condition


# ==================== 使用示例 ====================

if __name__ == "__main__":
    """
    过滤管理器使用示例
    
    这个示例展示了如何使用FilterConfigManager进行各种过滤操作。
    """
    
    print("=== 过滤配置管理器使用示例 ===")
    
    # 1. 创建管理器实例
    manager = FilterConfigManager()
    print("✓ 创建过滤管理器")
    
    # 2. 获取预定义规则
    organ_rules = manager.get_filter_rules(['organ_ids'])
    print(f"✓ 获取到 {len(organ_rules)} 个organ_id规则")
    
    # 3. 构建基本条件
    if organ_rules:
        condition1 = manager.build_condition_sql(organ_rules[0], ['org123', 'org456'])
        print(f"✓ 基本条件: {condition1}")
        
        # 4. 构建高级条件
        condition2 = manager.build_condition_sql_advanced(organ_rules[0], ['org123'], 'NOT IN')
        print(f"✓ 高级条件: {condition2}")
    
    # 5. 添加自定义规则
    custom_rule = FilterRule(
        name="status",
        table="device_table",
        field="device_status",
        field_type=FilterType.STRING,
        description="设备状态过滤"
    )
    manager.add_filter_rule("status", custom_rule)
    print("✓ 添加自定义规则")
    
    # 6. 使用自定义规则
    status_rules = manager.get_filter_rules(['status'])
    if status_rules:
        condition3 = manager.build_condition_sql(status_rules[0], 'active')
        print(f"✓ 自定义规则条件: {condition3}")
    
    # 7. 获取用户级别规则
    user_rules = manager.get_filter_rules(['user_level'])
    if user_rules:
        condition4 = manager.build_condition_sql(user_rules[0], 2)
        print(f"✓ 用户级别条件: {condition4}")
    
    print("\n=== 示例完成 ===")


def build_filter_condition_prompt(filter_conditions_json: str) -> str:
    """
    构建表过滤条件提示词
    
    生成用于SQL生成的过滤条件提示词，指导LLM如何正确应用表过滤条件。
    这个提示词强调了表名一致性、过滤条件应用规范和JOIN关系处理等关键原则。
    
    Args:
        filter_conditions_json (str): JSON格式的过滤条件字符串
    
    Returns:
        str: 完整的过滤条件提示词
    
    Examples:
        >>> filter_json = '{"l_lamppost": "organ_id IN (\'org123\',\'org456\')"}'
        >>> prompt = build_filter_condition_prompt(filter_json)
        >>> print(prompt)
        
    Note:
        这个函数用于统一管理过滤条件提示词，避免在多处重复定义相同的提示内容。
        当需要修改提示词时，只需在这里修改一次即可。
    """
    prompt = f"""
    表过滤条件是当前用户允许访问表的数据条件，生成SQL时需要严格遵循以下原则：

    1. 必须保持表名一致性：
        - 禁止随意替换或修改过滤条件中指定的表名
        - SQL语句中的表名必须与过滤条件中的表名完全一致才能应用该条件

    2. 过滤条件应用规范：
        - 仅当SQL查询中出现的表名与过滤条件指定的表名完全匹配时才可使用该条件
        - 杜绝任何表名不一致的引用情况

    3. JOIN关系处理：
        - 对于存在JOIN关系的表，避免添加重复的过滤条件
        - 确保过滤条件不会在JOIN操作中产生冗余

    4. 不需要解释，直接输出SQL查询语句
    
    5. 没有过滤条件时，直接输出SQL查询语句

    表过滤条件：
    {filter_conditions_json}
    """
    return prompt